package com.navinfo.tripanalysis.common.arithmetic.exception;

import com.navinfo.tripanalysis.common.config.ConfigMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 断言方法.
 * @author 水哥
 */
public class RangeAssert {
    private static Logger logger = LoggerFactory.getLogger(RangeAssert.class);


    /**
     * 判断数值是否在范围内,int类型.
     *
     * @param num           需要验证的数值
     * @param min           最小值
     * @param max           最大值
     * @param exceptionDesc 异常描述
     * @throws OutOfRangeException 数值范围异常时抛出
     */
    public static void numIsInTheRange(Integer num, int min, int max, String exceptionDesc) throws OutOfRangeException {
        CommonAssert.notNull(num);
        if (num < min || num > max) {
            throw new OutOfRangeException("num is out of range exception. [" + exceptionDesc + "],num:[" + num + "],min:[" + min + "],max:[" + max + "]");
        }
    }

    /**
     * 判断数值是否在范围内,int类型.
     *
     * @param num           需要验证的数值
     * @param min           最小值
     * @param max           最大值
     * @param exceptionDesc 异常描述
     * @throws OutOfRangeException 数值范围异常时抛出
     */
    public static void numIsInTheRange(Double num, double min, double max, String exceptionDesc) throws OutOfRangeException {
        CommonAssert.notNull(num);
        if (num < min || num > max) {
            throw new OutOfRangeException("num is out of range exception. [" + exceptionDesc + "],num:[" + num + "],min:[" + min + "],max:[" + max + "]");
        }
    }

    /**
     * 判断数值是否在范围内,int类型,返回boolean
     *
     * @param num           需要验证的数值
     * @param min           最小值
     * @param max           最大值
     * @param exceptionDesc 异常描述
     */
    public static boolean numIsInTheRangeB(double num, double min, double max, String exceptionDesc) {
        boolean flag = num > min && num < max;
        if (!flag) {
            logger.debug("num is out of range. [" + exceptionDesc + "],num:[" + num + "],min:[" + min + "],max:[" + max + "]", exceptionDesc, num, min, max);
        }
        return flag;
    }

    /**
     * 判断数值是否小于数值,int类型.
     *
     * @param num           需要验证的数值
     * @param threshold     阀值
     * @param exceptionDesc 异常描述
     * @throws OutOfRangeException 数值范围异常时抛出
     */
    public static void numIsLessThen(Integer num, int threshold, String exceptionDesc) throws OutOfRangeException {
        CommonAssert.notNull(num);
        if (num >= threshold) {
            throw new OutOfRangeException("num is not less then exception. [" + exceptionDesc + "],num:[" + num + "],threshold:[" + threshold + "]");
        }
    }

    /**
     * 判断数值是否小于数值,long类型.
     *
     * @param num           需要验证的数值
     * @param threshold     阀值
     * @param exceptionDesc 异常描述
     * @throws OutOfRangeException 数值范围异常时抛出
     */
    public static void numIsLessThen(Long num, long threshold, String exceptionDesc) throws OutOfRangeException {
        CommonAssert.notNull(num);
        if (num >= threshold) {
            throw new OutOfRangeException("num is not less then exception. [" + exceptionDesc + "],num:[" + num + "],threshold:[" + threshold + "]");
        }
    }

    /**
     * 判断数值是否大于数值,int类型.
     *
     * @param num           需要验证的数值
     * @param threshold     阀值
     * @param exceptionDesc 异常描述
     * @throws OutOfRangeException 数值范围异常时抛出
     */
    public static void numIsBiggerThen(Integer num, int threshold, String exceptionDesc) throws OutOfRangeException {
        CommonAssert.notNull(num);
        if (num <= threshold) {
            throw new OutOfRangeException("num is not bigger then exception. [" + exceptionDesc + "],num:[" + num + "],threshold:[" + threshold + "]");
        }
    }

    /**
     * 判断数值是否大于数值,long类型.
     *
     * @param num           需要验证的数值
     * @param threshold     阀值
     * @param exceptionDesc 异常描述
     * @throws OutOfRangeException 数值范围异常时抛出
     */
    public static void numIsBiggerThen(Long num, long threshold, String exceptionDesc) throws OutOfRangeException {
        CommonAssert.notNull(num);
        if (num <= threshold) {
            throw new OutOfRangeException("num is not bigger then exception. [" + exceptionDesc + "],num:[" + num + "],threshold:[" + threshold + "]");
        }
    }

    /**
     * 判断速度是否在范围内,单位km/h.
     *
     * @param speedKmh 速度，单位km/h
     * @throws OutOfRangeException 数值范围异常时抛出
     */
    public static void speedKmhIsInTheRange(Integer speedKmh) throws OutOfRangeException {
        numIsInTheRange(speedKmh, ConfigMap.getInteger("V_Spd_Min"), ConfigMap.getInteger("V_Spd_Max"), "速度验证");
    }

    /**
     * 判断加速度是否在范围内,单位米/平方秒.
     *
     * @param acceleratedSpeedMs2 加速度，单位m/s2
     * @return boolean
     */
    public static boolean acceleratedSpeedMs2IsInTheRange(double acceleratedSpeedMs2) {
        return numIsInTheRangeB(acceleratedSpeedMs2, ConfigMap.getDouble("H_Acc_Min"), ConfigMap.getDouble("H_Acc_Max"), "加速度验证");
    }


    /**
     * 油门开合度是否在范围内,单位%.
     *
     * @param accelerator 油门开合度
     * @throws OutOfRangeException 数值范围异常时抛出
     */
    public static void acceleratorIsInTheRange(Double accelerator) throws OutOfRangeException {
        numIsInTheRange(accelerator, ConfigMap.getDouble("Throt_Min"), ConfigMap.getDouble("Throt_Max"), "油门开合度验证");
    }

    /**
     * 判断速度是否在范围内.
     *
     * @param speedMs 速度，单位米/秒
     * @throws OutOfRangeException 数值范围异常时抛出
     */
    public static void speedIsInTheRange(double speedMs) throws OutOfRangeException {
        numIsInTheRange(speedMs, 0, 500.00, "速度验证");
    }

    /**
     * 判断时间间隔是否在范围内.
     *
     * @param millisecond 时间间隔，毫秒
     * @throws OutOfRangeException 数值范围异常时抛出
     */
    public static void millisecondIsInTheRange(long millisecond) throws OutOfRangeException {
        numIsBiggerThen(millisecond, 0L, "时间间隔验证");
    }

    /**
     * ECO经济驾驶引擎最小转速验证
     *
     * @param rotation 引擎转速，单位: RPM
     * @return boolean
     */
    public static boolean ecoDrivingRotationIsInTheRange(double rotation) {
        return numIsInTheRangeB(rotation, ConfigMap.getDouble("E_T_Min"), ConfigMap.getDouble("E_T_Max"), "ECO经济驾驶引擎转速验证");
    }


}
